package com.yhh.zhongdian.utils;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.yhh.zhongdian.MyApplication;
import com.yhh.zhongdian.base.BaseModelImpl;
import com.yhh.zhongdian.model.analyzeRule.AnalyzeHeaders;
import com.yhh.zhongdian.model.impl.IHttpGetApi;
import com.yhh.zhongdian.widget.modialog.ApkDownDialog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;

import io.reactivex.Observable;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 版本校验工具
 * Created by user on 20/3/11.
 */
public class VersionUtil {

    private static Gson gson = new Gson();

    public static class CheckVersionBo implements Serializable {
        private static final long serialVersionUID = 8344656483012954028L;
        /**
         * true 表示需要升级
         */
        public boolean update;

        /**
         * 下载的url
         */
        public String downUrl;

        /**
         * 版本号
         */
        public int code;

        /**
         * 更新内容
         */
        public String content;

        /**
         * 更新的时间
         */
        public long time;

        public CheckVersionBo() {
        }

        public CheckVersionBo(boolean update, String downUrl, String content, int code) {
            this.update = update;
            this.downUrl = downUrl;
            this.content = content;
            this.code = code;
            this.time = System.currentTimeMillis();
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public boolean isUpdate() {
            return update;
        }

        public void setUpdate(boolean update) {
            this.update = update;
        }

        public String getDownUrl() {
            return downUrl;
        }

        public void setDownUrl(String downUrl) {
            this.downUrl = downUrl;
        }

        public int getCode() {
            return code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public long getTime() {
            return time;
        }

        public void setTime(long time) {
            this.time = time;
        }

        @Override
        public String toString() {
            return "CheckVersionBo{" +
                    "update=" + update +
                    ", downUrl='" + downUrl + '\'' +
                    ", code=" + code +
                    ", content='" + content + '\'' +
                    ", time=" + time +
                    '}';
        }
    }

    public static Observable<CheckVersionBo> checkForUpdate(String checkUrl) {
        return BaseModelImpl.getInstance().getRetrofitString(StringUtils.getBaseUrl(checkUrl), "utf-8")
                .create(IHttpGetApi.class)
                .get(checkUrl, AnalyzeHeaders.getMap(null))
                .flatMap(s -> parseVersion(s.body()))
                .compose(RxUtils::toSimpleSingle);

    }

    private static Observable<CheckVersionBo> parseVersion(String json) {
        return Observable.create(e -> {
            try {
                Log.d("versionUtil", "download: " + json);
                JsonObject ans = gson.fromJson(json, JsonObject.class);
                ans = ans.getAsJsonObject("data");
                CheckVersionBo versionBo;
                int code = ans.get("version").getAsInt();
                if (code > MyApplication.getVersionCode()) {
                    // 版本升级
                    String url = "";
                    JsonElement element = ans.get("url");
                    if (element != null) {
                        url = element.getAsString();
                    }

                    MyApplication.getConfigPreferences().edit().putInt("show_ad_interval_time", ans.get("dm").getAsInt()).apply();
                    versionBo = new CheckVersionBo(url.length() > 0, url, ans.get("upLog").getAsString(), code);
                } else {
                    versionBo = new CheckVersionBo(false, "", "", MyApplication.getVersionCode());
                }

                e.onNext(versionBo);
                e.onComplete();
            } catch (Exception error) {
                // 下载失败，算出没有更新
                e.onNext(new CheckVersionBo(false, "", "", MyApplication.getVersionCode()));
                e.onComplete();
            }
        });
    }


    private static final OkHttpClient okHttpClient = new OkHttpClient();

    /**
     * @param url          下载连接
     * @param destFileDir  下载的文件储存目录
     * @param destFileName 下载文件名称
     * @param listener     下载监听
     */
    public static void download(final String url, final String destFileDir, final String destFileName, final ApkDownDialog.Callback listener) {
        Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败监听回调
                listener.onDownloadFailed(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                File dir = new File(destFileDir);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File file = new File(dir, destFileName);
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        // 下载中更新进度条
                        listener.onDownloading(progress);
                    }
                    fos.flush();
                    // 下载完成
                    listener.onDownloadSuccess(file);
                } catch (Exception e) {
                    listener.onDownloadFailed(e);
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                    }
                }
            }
        });
    }
}
